<?php
/**
 * 首屏广告
 *
 * @author Zeon <scplay@gmail.com>
 * @date 2019/6/3
 * @copyright PanxSoft Inc.
 */
namespace App\Http\Controllers\Admin\V1;


use App\Http\Controllers\ApiController;
use App\Http\Requests\Admin\V1\Device\DeviceDataRequest;
use App\Models\Device;
use App\Models\DeviceDescription;
use App\Models\Manufacture;
use App\Services\Utils\Transaction;
use Illuminate\Http\Request;

class DeviceController extends ApiController
{
    const ROUTES = [
        'index'   => 'admin.v1.Device.index',
        'create'   => 'admin.v1.Device.create',
        'store'   => 'admin.v1.Device.store',
        'update'  => 'admin.v1.Device.update',
        'destroy' => 'admin.v1.Device.destroy',
    ];

    public function index()
    {
        $devices = (new Device)
            ->oldest('sort_order')
            ->latest('created_at')
            ->latest('is_show')
            ->with('deviceDescriptions')
            ->paginate(\request()->get('per_page') ?: 15);;

        return $this->response(compact('devices'));
    }

    public function create()
    {
        $manufactures = (new Manufacture)->latest()->get();

        return $this->response(compact('manufactures'));
    }

    /**
     * @param DeviceDataRequest $request
     *
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function store(DeviceDataRequest $request)
    {
        $device = Transaction::handle(function () use ($request) {
            $device = (new Device)
                ->create($this->assembleDeviceStoreData($request));

            $this->createDeviceDescriptions($device, $request);

            return $device;
        });

        return $this->response(compact('device'));
    }

    /**
     * @param DeviceDataRequest $request
     * @param $key
     *
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function update(DeviceDataRequest $request, $key)
    {
        $device = (new Device)->find($key);
            $this->checkItemExist($device, trans('checker.admin.device'));

        $updated = Transaction::handle(function () use ($device, $request) {
            $device->deviceDescriptions()->delete();

            $this->createDeviceDescriptions($device, $request);

            return $device->update($this->assembleDeviceStoreData($request));
        });

        return $this->response(compact('device', 'updated'));
    }

    /**
     * @param $key
     *
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function destroy($key)
    {
        $device = (new Device)->find($key);
            $this->checkItemExist($device, trans('checker.admin.device'));

        $deleted = Transaction::handle(function () use ($device) {
            $device->deviceDescriptions()->delete();

            return $device->delete();
        });

        return $this->response(compact('deleted'));
    }

    private function assembleDeviceStoreData(Request $request): array
    {
        return $request->only([
            'manufacture_id', 'name', 'sort_order',
            'is_show', 'bluetooth_code', 'remark',
            'price', 'product_img',
            'luminance_min', 'luminance_max',
            'color_temperature_min', 'color_temperature_max',
            'service_uuid', 'read_uuid', 'write_uuid',
        ]);
    }

    /**
     * @param Device $device
     * @param Request|DeviceDataRequest $request
     *
     * @return array
     */
    private function createDeviceDescriptions(Device $device, Request $request): array
    {
        /**
         * 注意这里必须这么取值，不能使用 —>get('descriptions') ，这样会导致文件参数丢失，
         * 因为只有 __get() 会调用 request->all()
         * 其中合并了 request->input() 与 request->allFiles()
         */
        $descriptions = $request->descriptions;

        return array_map(function (array $description, int $language_id) use ($device) {
            return (new DeviceDescription)->create([
                'device_id'       => $device->getKey(),
                'language_id'     => $language_id,
                'name'            => $description['name'],
                'instruction_img' => $description['instruction_img'] ?? '',
                'help_img'        => $description['help_img'] ?? '',
            ]);
        }, $descriptions, array_keys($descriptions));
    }
}